﻿import QtQuick 2.14
import QtCharts 2.14
import QtQuick.Controls 2.14
import "../style.js" as Style

/*
    条形图控件
*/
ChartView {
    id:controlRoot

    //数据模型，其格式如下：
    //[
    //  {"color":"","label":"","value":[]}   //一条数据代表一个BarSet(一个条形组)
    //  {"color":"","label":"","value":[]}   //color为该BarSet的颜色，label为该BarSet名称，value为该BarSet在坐标轴上每个类别的值
    //]
    property var    model:[]
    property string type:"vertical"         //条形图方向：horizontal（水平条形图）、vertical（垂直条形图）

    //条形块样式
    property real   barSetScaleSize:0.7              //条形块总宽度比例（0~1，1代表充满整个坐标区间）
    property int    barSetBorderWidth:1              //条形块边框宽度
    property color  barSetBorderColor:"white"         //条形块边框颜色
    property string barSetLabelFormat:"@value"       //条形块标签格式（@value表示对值的引用）
    property bool   barSetLabelVisble:true            //是否显示条形块标签
    property int    barSetLabelPosition:AbstractBarSeries.LabelsCenter  //条形块标签位置
    property color  barSetLabelColor:"white"          //条形块标签字体颜色
    property string barSetLabelFontFamily:Style.string_textFamily   //条形块标签的字体族
    property int    barSetLabelFontSize:12            //条形块标签的字体大小
    property int    barSetLabelPrecision:6             //条形块标签有效数字位数
    property bool   barSetToolTipVisible:true         //是否显示条形块工具提示

    //坐标轴
    property alias  valueAxis:valueAxis
    property alias  categoryAxis: categoryAxis

    //信号
    signal barSetClicked(var index,var barset)

    //图例样式
    legend.alignment:Qt.AlignBottom
    legend.visible: true
    legend.font.pixelSize: barSetLabelFontSize
    legend.font.family: barSetLabelFontFamily
    legend.markerShape:Legend.MarkerShapeRectangle

    width: 400
    height: 300
    antialiasing: true
    animationDuration: 500
    dropShadowEnabled: false
    backgroundRoundness:0
    animationOptions: ChartView.AllAnimations
    theme:ChartView.ChartThemeLight

    BarCategoryAxis{
        id:categoryAxis
        gridVisible: false
        labelsFont.pixelSize: barSetLabelFontSize
        labelsFont.family: barSetLabelFontFamily
    }

    ValueAxis{
        id:valueAxis
        gridVisible:true
        min:0
        max:0
        tickCount:5
        labelFormat: "%f"
        labelsFont.pixelSize: barSetLabelFontSize
        labelsFont.family: barSetLabelFontFamily
    }

    Menu{
        id:toolTip
        property string text:""
        width: toolTipText.contentWidth+20
        height: toolTipText.contentHeight
        background: Rectangle{
            color: "black"
            radius: 5
            opacity: 0.5
        }
        Text {
            id:toolTipText
            text: toolTip.text
            font.pixelSize: barSetLabelFontSize
            font.family: barSetLabelFontFamily
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            color: "white"
        }
    }

    onModelChanged: {
        var barSeries
        if(controlRoot.count>0){
            barSeries = controlRoot.series(0)
        }else{
            if(type=="horizontal"){
                barSeries=controlRoot.createSeries(ChartView.SeriesTypeHorizontalBar,"s1",valueAxis,categoryAxis)
            }else{
                barSeries=controlRoot.createSeries(ChartView.SeriesTypeBar,"s1",categoryAxis,valueAxis)
            }

            barSeries.hovered.connect(__onBarSetHoverd)
            barSeries.clicked.connect(function(index, barset){
               barSetClicked(index,barSet)
            })

            barSeries.labelsVisible = barSetLabelVisble
            barSeries.labelsPosition = barSetLabelPosition
            barSeries.labelsFormat = barSetLabelFormat
            barSeries.labelsPrecision = barSetLabelPrecision
        }

        barSeries.clear()

        for(var i1 in model){
            var barSetColor= model[i1].color
            var barSetLabel= model[i1].label
            var barSetValues= model[i1].value

            if(valueAxis.max===0){
                var maxValue =  __getModelMaxValue(barSetValues)
                valueAxis.max = maxValue
            }

            var barSet = barSeries.append(barSetLabel,barSetValues)
            barSet.color =barSetColor
            barSet.borderWidth=barSetBorderWidth
            barSet.borderColor=Qt.binding(function(){
                if(barSetBorderWidth==0){
                    return barSetColor
                }else{
                    return barSetBorderColor
                }
            })
            barSet.labelColor=barSetLabelColor
            barSet.labelFont.family=barSetLabelFontFamily
            barSet.labelFont.pixelSize=barSetLabelFontSize
            barSet.label=barSetLabel
        }

    }

    //鼠标悬浮在某个BarSet上时执行
    //status：true（进入），false（离开）
    //index: 索引
    //barset：BarSet对象
    function __onBarSetHoverd(status,index,barset){
        if(barSetToolTipVisible){
            if(status){
                toolTip.text=barset.label+"\n"+categoryAxis.categories[index]+":"+barset.values[index]
                toolTip.popup()
            }else{
                toolTip.close()
            }
        }
    }

    //获取model[i].value的最大值
    function __getModelMaxValue(modelValue){
        var maxValue
        for(var i=0;i<modelValue.length;i++){
            if(i===0){
               maxValue = modelValue[i]
            }else{
                if(modelValue[i]>maxValue){
                    maxValue = modelValue[i]
                }
            }
        }

        return maxValue
    }
}

